const webpack = require("webpack");
const EventEmitter = require("events");
const path = require("path");
const { createFsFromVolume, Volume } = require("memfs");
const nodeFs = require("fs");
const WebpackDevServer = require('webpack-dev-server');

module.exports = class Service extends EventEmitter {
  constructor(context) {
    super();
    process._0XG_CLI_SERVICE = this;
    this.initialized = false;
    this.context = context;
    this.modes = {};

    console.log("---- context --> ", context);
    this.cfg = require(path.join(context, "config.js"));
    console.log("---- this.cfg --> ", this.cfg);
  }

  mergeConfig = () => {
    const defaultCfg = {
      mode: "none",
      entry: "./src/app.js",
    };

    return { ...defaultCfg, ...this.cfg };
  };

  logStats = (err, stats) => {
    if (err) {
      console.error(err.stack || err);
      if (err.details) {
        console.error(err.details);
      }
      return;
    }

    const info = stats.toString({
      chunks: false,  // 使构建过程更静默无输出
      colors: true    // 在控制台展示颜色
    });

    nodeFs.writeFileSync(path.join(this.context, 'build.log'), JSON.stringify(stats.toJson(), null, 2));

    if (stats.hasErrors()) {
      console.error(info.errors);
    }

    if (stats.hasWarnings()) {
      console.warn(info.warnings);
    }

    console.log(info);
  }

  run(name = "none", args = {}, rawArgv = []) {
    const mode =
      args.mode ||
      (name === "build" && args.watch ? "development" : this.modes[name]);

    const mergeCfg = this.mergeConfig();
    const compiler = webpack(mergeCfg);
    compiler.run((err, stats) => {
      this.logStats(err, stats);

      compiler.close((closeErr) => {
        // ...
      });
    });
  }

  async watch(name = "none", args = {}, rawArgv = []) {
    const mode =
      args.mode ||
      (name === "build" && args.watch ? "development" : this.modes[name]);
    const mergeCfg = this.mergeConfig();
    const compiler = webpack(mergeCfg);

    // 使用 webpack-dev-server
    // const devServerOptions = { open: true };
    // const server = new WebpackDevServer(devServerOptions, compiler);
    // console.log('Starting server...');
    // await server.start();

    // 使用内存文件系统
    const fs = createFsFromVolume(new Volume());
    compiler.outputFileSystem = fs;
    const watching = compiler.watch(
      {
        aggregateTimeout: 300,
        poll: undefined,
      },
      (err, stats) => {
        this.logStats(err, stats);
      },
    );
  }
};
